﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WjAutoConfigApp.Common;
using WjAutoConfigApp.Properties;

namespace WjAutoConfigApp
{
    public partial class MainForm : Form
    {
        #region 变量

        private Graphics graphics;
        private Bitmap myBmp;

        /// <summary>
        /// 是否带索引的图像
        /// </summary>
        private bool isIndexPic;

        /// <summary>
        /// 用于存储带索引的图片
        /// </summary>
        private Image indexImage;
        /// <summary>
        /// 主图的路径
        /// </summary>
        private string mainImageFilePath;
        /// <summary>
        /// 存储打开的图片文件列表
        /// </summary>
        private List<PictureBox> pictureBoxes = new List<PictureBox>();
        /// <summary>
        /// 存储打开的图片文件列表以及打开文件的原始路径
        /// </summary>
        private Dictionary<PictureBox, string> dicPicPath = new Dictionary<PictureBox, string>();
        /// <summary>
        /// 记录鼠标左键点下的坐标位置
        /// </summary>
        private Point mouseDownPoint = new Point();//记录鼠标点击左键时的坐标位置

        /// <summary>
        /// 是否移动
        /// </summary>
        private bool _isMove { get; set; }
        /// <summary>
        /// 标记鼠标是否位拖动状态
        /// </summary>
        private bool IsMove
        {
            get { return _isMove; }
            set
            {
                _isMove = value;
                if (_isMove)
                {
                    mainPictureBox.Cursor = Cursors.SizeAll;
                }
                else
                {
                    if (IsBeginDraw)
                    {
                        mainPictureBox.Cursor = Cursors.Cross;
                    }
                    else
                    {
                        mainPictureBox.Cursor = Cursors.Default;
                    }
                }
            }
        }

        /// <summary>
        /// 滚轮步长
        /// </summary>
        private const int zoomStep = 100;

        /// <summary>
        /// 最小图片宽度
        /// </summary>
        private const int minWith = 100;

        /// <summary>
        /// 宽度放大或缩小的最终值
        /// </summary>
        private int ZoomVarX { get; set; }

        /// <summary>
        /// 高度放大或缩小的最终值
        /// </summary>
        private int ZoomVarY { get; set; }

        /// <summary>
        /// 原始图片的宽度
        /// </summary>
        private int OriginMainPicWith { get; set; }

        /// <summary>
        /// 原始图片的高度
        /// </summary>
        private int OriginMainPicHight { get; set; }

        private bool _isBeginDraw;
        /// <summary>
        /// 是否开始绘制
        /// </summary>
        private bool IsBeginDraw
        {
            get { return _isBeginDraw; }
            set
            {
                _isBeginDraw = value;
                if (_isBeginDraw)

                {
                    mainPictureBox.Cursor = Cursors.Cross;
                }
                else
                {
                    mainPictureBox.Cursor = Cursors.Default;
                }
            }
        }

        /// <summary>
        /// 绘制的图形类别
        /// </summary>
        private ShapeType shapeType;

        /// <summary>
        /// 是否已经打开了一张大图
        /// </summary>
        private bool isOpenBigPic;

        /// <summary>
        /// 是否已经完成绘制
        /// </summary>
        private bool _isFinished;

        public bool IsFinished
        {
            get { return _isFinished; }
            set
            {
                _isFinished = value;
                IsBeginDraw = false;
                if (_isFinished && shapeType.Equals(ShapeType.Polygon) && mainImageFilePath != null)
                {
                    Editpolygon(penColor);
                    //TO DO 完成后需要对区域的像素设置对应的属性
                    var dialogResult = CommomMethod.ShowInfomationDialog("对已勾选完成区域的像素设置属性信息！","步骤2：");
                    if (dialogResult == DialogResult.Cancel) return;
                    GlobleCache.areaModel.PerfectModel(penColor);
                    SelectTpyeForm form = new SelectTpyeForm();
                    form.ShowDialog();
                }
            }
        }


        /// <summary>
        /// 记录当前所画点的序号
        /// </summary>
        private int pointIndex = 0;


        private Color penColor;

        private string laneCsvPath;

        private string lanePropertyCsvPath;
        private string savePath;
        private string areaJsonPath;

        /// <summary>
        /// 修改或是新建
        /// </summary>
        private bool isEdit;

        #endregion

        public MainForm()
        {
            InitializeComponent();
        }


        #region 功能区

        /// <summary>
        /// 窗口加载程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            pictureBoxes.Add(pictureBox1);
            pictureBoxes.Add(pictureBox2);
            pictureBoxes.Add(pictureBox3);
            pictureBoxes.Add(pictureBox4);
            //设置打开按钮在父控件的中心
            SetContolCenter(lab_Open1, lab_Open2);

            

        }

        /// <summary>
        /// 菜单--打开主资源
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 打开主资源ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            isEdit = false;
            OpenPictureFile(PictureBoxSizeMode.Zoom, false);
            lab_Open1.Visible = false;
        }

        /// <summary>
        /// 菜单--打开辅助资源
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 打开辅助资源ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenPictureFile(PictureBoxSizeMode.StretchImage, true);
            lab_Open2.Visible = false;
        }

        /// <summary>
        /// 菜单--修改已有配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void editExistConfiguration_Click(object sender, EventArgs e)
        {
            isEdit = true;
            if (!OpenPictureFile(PictureBoxSizeMode.Zoom, false))
                return;
            lab_Open1.Visible = false;
            RefreshBmp();
        }

        /// <summary>
        /// 打开主图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lab_Open1_Click(object sender, EventArgs e)
        {
            isEdit = false;
            OpenPictureFile(PictureBoxSizeMode.Zoom, false);
            lab_Open1.Visible = false;
        }

        /// <summary>
        /// 打开辅助图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lab_Open2_Click(object sender, EventArgs e)
        {
            OpenPictureFile(PictureBoxSizeMode.StretchImage, true);
            lab_Open2.Visible = false;
        }


        /// <summary>
        /// 滚轮拖动放大
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainPictureBox_MouseWheel(object sender, MouseEventArgs e)
        {
            if (myBmp is null) return;
            if (e.Delta > 0)
            {
                mainPictureBox.Width += zoomStep;
                mainPictureBox.Height = mainPictureBox.Width * OriginMainPicHight / OriginMainPicWith;
                ZoomVarX += zoomStep;
                ZoomVarY = mainPictureBox.Height - OriginMainPicHight;
                //Console.WriteLine($"X轴方向增加：{zoomStep}->{ZoomVarX},Y轴方向增加{mainPictureBox.Height -OriginMainPicHight}->{ZoomVarY}");
            }
            if (e.Delta < 0)
            {
                if (mainPictureBox.Width <= minWith)
                    return;

                mainPictureBox.Width -= zoomStep;
                mainPictureBox.Height = mainPictureBox.Width * OriginMainPicHight / OriginMainPicWith;
                ZoomVarX -= zoomStep;
                ZoomVarY = mainPictureBox.Height - OriginMainPicHight;
                //Console.WriteLine($"X轴方向减小：{zoomStep}->{ZoomVarX},Y轴方向减小{mainPictureBox.Height - OriginMainPicHight}->{ZoomVarY}");
            }
        }

        /// <summary>
        /// 在图像上点击左键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainPictureBox_MouseDown(object sender, MouseEventArgs e)
        {

            //按压鼠标中间的按键同样可以完成对应的图像移动事件
            if (e.Button == MouseButtons.Middle)
            {
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
                IsMove = true;
                mainPictureBox.Focus();
            }
            if (e.Button == MouseButtons.Left && IsBeginDraw)
            {
                RestPointList();
                Point point = ConvertRalativeLocation();
                GlobleCache.areaModel.Points.Add(new Point(point.X, point.Y));
            }
            if (e.Button == MouseButtons.Right && IsBeginDraw)
            {
                IsFinished = true;
            }
        }

        

        /// <summary>
        /// 鼠标在Picture移动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            //显示对应的坐标点
            var point = ConvertRalativeLocation();
            imagePxPointLocation.Text = "像素:" + (point.X) + "," + (point.Y);
            if (IsMove)
            {
                var dx = Cursor.Position.X - mouseDownPoint.X;
                var dy = Cursor.Position.Y - mouseDownPoint.Y;
                var x = mainPictureBox.Location.X + dx;
                var y = mainPictureBox.Location.Y + dy;
                mainPictureBox.Location = new Point(x, y);
                mouseDownPoint.X = Cursor.Position.X;
                mouseDownPoint.Y = Cursor.Position.Y;
            }
        }



        /// <summary>
        /// 点击图像画板鼠标弹起事件
        /// 1.取消移动
        /// 2.开始绘画
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                DrawGraph(shapeType, penColor);
            }
            if (e.Button == MouseButtons.Middle)
            {
                IsMove = false;
            }
        }


        /// <summary>
        /// 点击绘制多边形
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            var isPicLoad = IsLoadMainPicCompeleted();
            if (!isPicLoad) return;
            //提示开始顺时针描点画
            var dialogResult = CommomMethod.ShowInfomationDialog("用鼠标点击要绘制区域的各个顶点，依次顺时针方向选取，完成后点击【完成绘制】按钮或点击右键完成绘制！","步骤1：");
            if (dialogResult == DialogResult.Cancel) return;
            //Color color = penColor;
            if (!SelectPenColor()) return;
            //SaveFinishArea(color);
            ////清除上一个画图点集合
            //ClearAreaModel();
            pointIndex = 0;
            IsBeginDraw = true;
            shapeType = ShapeType.Polygon;
        }
        

        /// <summary>
        /// 绘制完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            if (GlobleCache.areaModel is null || GlobleCache.areaModel.Points.Count == 0)
            {
                CommomMethod.ShowMsg("请先绘制封闭区域");
                return;
            }
            IsFinished = true;
        }

        /// <summary>
        /// 设置属性
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            if (GlobleCache.areaModel is null || GlobleCache.areaModel.Points.Count == 0)
            {
                CommomMethod.ShowMsg("请先绘制封闭区域");
                return;
            }
            if (_isFinished && shapeType.Equals(ShapeType.Polygon) && mainImageFilePath != null)
            {
                GlobleCache.areaModel.PerfectModel(penColor);
                SelectTpyeForm form = new SelectTpyeForm();
                form.ShowDialog();
            }
        }

        /// <summary>
        /// 上一步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            if (GlobleCache.areaModel.Points.Count == 0) return;
            //重新加载图像的位置并保持图像当前的位置和大小
            Reset();
            if (IsFinished)
            {
                IsFinished = false;
                IsBeginDraw = true;
            }

            //重新画多边形
            //1.1 画出已经完成的封闭图形
            DrawExistAreas();
            //1.2 画出正在画的多边形
            Editpolygon(penColor, false, true);
        }

        

        /// <summary>
        /// 下一步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            if (IsFinished) return;
            Reset();
            //1.1 画出已经完成的封闭图形
            DrawExistAreas();
            //1.2画出正在画的多边形
            Editpolygon(penColor, true, true);
            if(pointIndex == GlobleCache.areaModel.Points.Count&&GlobleCache.areaModel.Points.Count>2 && !IsFinished)
            {
                IsFinished = true;
            }
        }

        /// <summary>
        /// 重新绘制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            if(CommomMethod.ShowInfomationDialog("重置后所有设置内容以及绘制区域将全部消失，是否重置？","警告")!= DialogResult.OK)
            {
                return;
            }
            Reset(true);
            GlobleCache.areaList.Clear();
            GlobleCache.areaModel.Points.Clear();
            pointIndex = 0;
            IsFinished = false;
            IsBeginDraw = false;
        }

        /// <summary>
        /// 退出保存的时候需要询问是否保存已经标注好的内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //1.先检查是否存在主图片文件
            if (mainImageFilePath is null) return;
            //2.固化内存配置文件内容
            SaveCsvFile();
            SaveGlobleAreasJsonFile();
            if (File.Exists(lanePropertyCsvPath))
            {
                var result = CommomMethod.ShowInquiryDialog("是否保存已生成的配置文件！");
                if (result != DialogResult.OK)
                {
                    return;
                }
                else
                {
                    //保存到一个文件夹中
                    if (!Directory.Exists(savePath))
                    {
                        Directory.CreateDirectory(savePath);
                    }
                    if (File.Exists(laneCsvPath))
                    {
                        FileInfo laneFile = new FileInfo(laneCsvPath);
                        laneFile.CopyTo(savePath + ConstantValue.LANECSV, true);
                    }
                    FileInfo propertyFile = new FileInfo(lanePropertyCsvPath);
                    propertyFile.CopyTo(savePath + ConstantValue.TRAFFIC_CONFIG, true);
                    myBmp?.Save(savePath + "temp.bmp", ImageFormat.Bmp);

                }
            }
        }




        /// <summary>
        /// 重新加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            if(CommomMethod.ShowInquiryDialog("重新加载后数据将全部丢失，并可加载其它图片，是否重新加载？") != DialogResult.OK)
            {
                return;
            }
            myBmp = null;
            mainPictureBox.Image = null;
            foreach (var pictureBox in pictureBoxes)
            {
                pictureBox.Image = null;
            }
            mainPictureBox.Location = new Point(0, 0);
            mainPictureBox.Width = 400;
            mainPictureBox.Height = 200;
            //IsFinished = true;
            IsBeginDraw = false;
            isOpenBigPic = false;
            GlobleCache.areaList.Clear();
            ClearAreaModel();
            IsMove = false;
            //显示加载图像按钮
            lab_Open1.Visible = true;
            lab_Open2.Visible = true;
            ZoomVarX = 0;
            ZoomVarY = 0;
            dicPicPath.Clear();
        }

        /// <summary>
        /// 窗口放大缩小事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            //设置打开按钮在父控件的中心
            SetContolCenter(lab_Open1, lab_Open2);
        }

        /// <summary>
        /// 显示大图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            var pictureBox = sender as PictureBox;
            if (dicPicPath.Count == 0) return;
            //只允许打开一次
            if (isOpenBigPic)
            {
                MessageBox.Show("只能放大单张图片！如果切换图片请关闭当前图片！");
                return;
            }
            BigPictureForm bigPictureForm = new BigPictureForm(dicPicPath[pictureBox]);
            bigPictureForm.DoSomeThing += () => { isOpenBigPic = false; };
            bigPictureForm.Show();
            isOpenBigPic = true;
        }

        /// <summary>
        /// 刷新当前画布内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton9_Click(object sender, EventArgs e)
        {
            RefreshBmp();
        }

        /// <summary>
        /// 保存文档功能
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton8_Click(object sender, EventArgs e)
        {
            try
            {
                SaveCsvFile();
                SaveGlobleAreasJsonFile();
                CommomMethod.ShowMsg("保存成功");
            }
            catch (Exception ex)
            {
                CommomMethod.ShowMsg(ex.Message);
            }
        }

        /// <summary>
        /// 取消绘画
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripLabel5_Click(object sender, EventArgs e)
        {
            IsBeginDraw = !IsBeginDraw;
            if (IsBeginDraw)
            {
                toolStripLabel5.Image = (Bitmap)Resources.暂停.Clone();
                toolStripLabel5.Text = "暂停绘图";
            }
            else
            {
                toolStripLabel5.Image = (Bitmap)Resources.开始.Clone();
                toolStripLabel5.Text = "继续绘图";
            }
        }


        /// <summary>
        /// 右键操作对应的区域内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainPictureBox_MouseClick(object sender, MouseEventArgs e)
        {

            if (e.Button == MouseButtons.Right)
            {
                if (mainImageFilePath is null || GlobleCache.areaList.Count == 0) return;
                //1.判断点击的位置是否在所画区域中，并且重叠部分超过三个框时需要提示不能在超过三个重叠区域。
                GlobleCache.fitAreas.Clear();
                var point = ConvertRalativeLocation();
                foreach (var model in GlobleCache.areaList)
                {
                    var isIn = CommomMethod.IsInPolygon(point, model.Points);
                    if (isIn) GlobleCache.fitAreas.Add(model);
                }

                if (GlobleCache.fitAreas.Count == 0) return;
                if (GlobleCache.fitAreas.Count >= 3)
                {
                    CommomMethod.ShowMsg($"当前点击区域存在{GlobleCache.fitAreas.Count}个重叠区域，无法操作！");
                    return;
                }
                if (GlobleCache.fitAreas.Count == 2 && GlobleCache.fitAreas.GroupBy(area => area.IsLaneArea).Count() != 2)
                {
                    //判断两个区域是否属于同一个类型
                    CommomMethod.ShowMsg($"当前点击区域存在两个{(GlobleCache.fitAreas.First().IsLaneArea ? "车道" : "属性")}区域，无法操作");
                    return;
                }

                this.contextMenu.Show(MousePosition.X, MousePosition.Y);
            }
        }

        /// <summary>
        /// 删除车道区域
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 删除车道ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //1.清除缓存中的车道信息
            CSVHelper.DeleteLaneInfo();
            //2.刷新当前绘图
            RefreshBmp();

        }

        /// <summary>
        /// 删除车道属性区域
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 删除局部属性ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //1.重置对应区域CSV信息并删除对应的区域图像缓存
            CSVHelper.DeleteLanePropertyInfo();
            //2.刷新当前绘图
            RefreshBmp();
        }

        /// <summary>
        /// 修改车道信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 修改车道信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var areaModel = GlobleCache.fitAreas.Where(area => area.IsLaneArea).FirstOrDefault();
            if (areaModel is null)
            {
                CommomMethod.ShowMsg("修改的不是完整车道区域！");
                return;
            }
            GlobleCache.areaModel = areaModel;
            LaneAllPropertiesSetingForm form = new LaneAllPropertiesSetingForm();
            form.Show();
        }

        /// <summary>
        /// 修改局部属性信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 修改局部属性信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var areaModel = GlobleCache.fitAreas.Where(area => !area.IsLaneArea).FirstOrDefault();
            if (areaModel is null)
            {
                CommomMethod.ShowMsg("修改的不是车道属性区域！");
                return;
            }
            GlobleCache.areaModel = areaModel;
            LanePartPropertySetingForm form = new LanePartPropertySetingForm();
            form.Show();
        }

        #endregion




        #region 方法区

        /// <summary>
        /// 打开BMP图
        /// </summary>
        private bool OpenPictureFile(PictureBoxSizeMode sizeMode, bool isMultiSelect)
        {
            //点击弹出对话框
            OpenFileDialog openFileDialog = new OpenFileDialog();

            //设置对话框的标题
            openFileDialog.Title = "请选择要打开的图片";

            //设置对话框可以多选
            openFileDialog.Multiselect = isMultiSelect;

            //设置对话框的文件类型
            openFileDialog.Filter = "所有文件|*.*|bmp图片|*.bmp|jpg图片|*.jpg|png图片|*.png";

            //展示对话框
            var result = openFileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                if (!isMultiSelect)
                {
                    //获得在打开的对话框中选中文件的路径
                    mainImageFilePath = openFileDialog.FileName;
                    InitFilePath();
                    if (isEdit)
                    {
                        if (!File.Exists(areaJsonPath))
                        {
                            CommomMethod.ShowMsg($"{areaJsonPath}区域信息文件不存在！");
                            return false;
                        }
                        if (!File.Exists(laneCsvPath) || !File.Exists(lanePropertyCsvPath))
                        {
                            CommomMethod.ShowMsg($"{laneCsvPath}或{lanePropertyCsvPath}配置文件不存在！");
                            return false;
                        }
                        DeSerializeFile();
                    }
                    indexImage = Image.FromFile(mainImageFilePath);
                    InitBitmap();
                    InitGraphics();
                    if (isIndexPic)
                    {
                        graphics.DrawImage(indexImage, 0, 0);
                    }
                    mainPictureBox.Image = myBmp;
                    mainPictureBox.SizeMode = sizeMode; //设置picturebox为缩放模式
                    if (sizeMode == PictureBoxSizeMode.Zoom)
                    {
                        OriginMainPicWith = mainPictureBox.Width = myBmp.Width;
                        OriginMainPicHight = mainPictureBox.Height = myBmp.Height;
                        //初始化CSV文档
                        InitCsvFileAndLoad();
                    }
                }
                else
                {
                    string[] imageFiles = openFileDialog.FileNames;
                    for (int i = 0; i < imageFiles.Length; i++)
                    {
                        if (i >= pictureBoxes.Count) return true;
                        var myBmp = new Bitmap(imageFiles[i]);
                        pictureBoxes[i].Image = myBmp;
                        pictureBoxes[i].SizeMode = sizeMode;
                        if (sizeMode == PictureBoxSizeMode.Zoom)
                        {
                            pictureBoxes[i].Width = myBmp.Width;
                            pictureBoxes[i].Height = myBmp.Height;
                        }
                        dicPicPath.Add(pictureBoxes[i], imageFiles[i]);
                    }
                }
                return true;
            }
            return false;
        }

        #region 画图过程
        /// <summary>
        /// 画图
        /// </summary>
        public void DrawGraph(ShapeType type, Color color)
        {
            if (!IsBeginDraw) return;
            switch (type)
            {
                case ShapeType.Text:
                    break;
                case ShapeType.StraightLine:
                    break;
                case ShapeType.Polygon:
                    Editpolygon(color);
                    break;
                default:
                    break;
            }
        }



        /// <summary>
        /// 修改正在绘制的多边形
        /// </summary>
        /// <param name="color">颜色</param>
        /// <param name="isIndexAdd">前进或后退</param>
        /// <param name="isMore">是否连续多点绘制</param>
        private void Editpolygon(Color color, bool isIndexAdd = true,bool isMore = false)
        {
            ChangePointIndex(isIndexAdd);
            Drawpolygon(color, isMore);
        }

        /// <summary>
        /// 画多边形
        /// </summary>
        /// <param name="color"></param>
        /// <param name="isMore"></param>
        private void Drawpolygon(Color color, bool isMore = false)
        {
            Pen pen = new Pen(color);
            DrawLine(pen, pointIndex, isMore);
            DrawPoint(pen, pointIndex, isMore);
        }

        /// <summary>
        /// 刷新当前画布信息
        /// </summary>
        private void RefreshBmp()
        {
            //重新加载图像的位置并保持图像当前的位置和大小
            Reset();
            //重新画多边形
            //1.1 画出已经完成的封闭图形
            DrawExistAreas();
            //1.2 画出正在画的多边形
            //Drawpolygon(penColor, true);
        }

        /// <summary>
        /// 画点
        /// </summary>
        /// <param name="color"></param>
        /// <param name="pen"></param>
        /// <param name="pointIndex"></param>
        /// <param name="isMore">是否画多点</param>
        private void DrawPoint(Pen pen, int pointIndex, bool isMore = false)
        {
            if (_isBeginDraw)
            {
                if (isMore)
                {
                    for (int i = 0; i < pointIndex; i++)
                    {
                        graphics.DrawEllipse(pen, GlobleCache.areaModel.Points[pointIndex - 1].X, GlobleCache.areaModel.Points[pointIndex - 1].Y, 2, 2);
                    }
                }
                else
                {
                    graphics.DrawEllipse(pen, GlobleCache.areaModel.Points[pointIndex - 1].X, GlobleCache.areaModel.Points[pointIndex - 1].Y, 2, 2);
                }
            }
        }

        /// <summary>
        /// 划线
        /// </summary>
        /// <param name="pen">画笔</param>
        /// <param name="pointIndex">当前画点的角标</param>
        /// <param name="isMore">上否连续多点划线</param>
        private void DrawLine(Pen pen, int pointIndex, bool isMore = false)
        {
            if (_isBeginDraw)
            {
                if (GlobleCache.areaModel.Points.Count > 1 && pointIndex > 1)
                {
                    if (isMore)
                    {
                        for (int i = 0; i < pointIndex-1; i++)
                        {
                            graphics.DrawLine(pen, GlobleCache.areaModel.Points[i+1], GlobleCache.areaModel.Points[i]);
                        }
                    }
                    else
                    {

                        graphics.DrawLine(pen, GlobleCache.areaModel.Points[pointIndex - 2], GlobleCache.areaModel.Points[pointIndex - 1]);
                    }
                }

            }
            else
            {
                if (GlobleCache.areaModel.Points.Count >= 3)
                    graphics.DrawLine(pen, GlobleCache.areaModel.Points[GlobleCache.areaModel.Points.Count - 1], GlobleCache.areaModel.Points[0]);
            }

            mainPictureBox.Image = myBmp;
        }
        #endregion

        /// <summary>
        /// 转换图片像素的相对位置
        /// </summary>
        /// <returns></returns>
        private Point ConvertRalativeLocation()
        {
            Point point = new Point();
            Point pxy = mainPictureBox.PointToClient(Control.MousePosition);
            if (ZoomVarX != 0)
            {
                point.X = pxy.X * OriginMainPicWith / (OriginMainPicWith + ZoomVarX);
                point.Y = pxy.Y * OriginMainPicHight / (OriginMainPicHight + ZoomVarY);
            }
            else
            {
                point.X = pxy.X;
                point.Y = pxy.Y;
            }
            return point;
        }

        /// <summary>
        /// 设置控件在父控件的中间显示
        /// </summary>
        /// <param name="control"></param>
        private void SetContolCenter(params Control[] controls)
        {
            foreach (var control in controls)
            {
                Control parentControl = control.Parent;
                if (parentControl is null)
                {
                    return;
                }
                control.Location = new Point(parentControl.ClientSize.Width / 2 - control.Width / 2, parentControl.Height / 2 - control.Height / 2);
            }

        }

        /// <summary>
        /// 选择画笔颜色
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private bool SelectPenColor()
        {
            ColorDialog colorDia = new ColorDialog();
            if (colorDia.ShowDialog() == DialogResult.OK)
            {
                //获取画笔所选择的颜色
                penColor = colorDia.Color;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断主图是否加载完成
        /// </summary>
        /// <returns></returns>
        private bool IsLoadMainPicCompeleted()
        {
            if (myBmp is null)
            {
                MessageBox.Show("请先加载主图片！");
                return false;
            }
            return true;
        }



        /// <summary>
        /// 画出已经存在的多边形
        /// </summary>
        private void DrawExistAreas()
        {
            foreach (var area in GlobleCache.areaList)
            {
                Pen pen = new Pen(area.PenColor);
                graphics.DrawPolygon(pen, area.Points.ToArray());
                foreach (var point in area.Points)
                {
                    graphics.DrawEllipse(pen, point.X, point.Y, 2, 2);
                }
            }
        }

        /// <summary>
        /// 改变当前点集的指针 PointIndex
        /// </summary>
        /// <param name="isAdd">是否加1</param>
        private void ChangePointIndex(bool isAdd)
        {
            if (isAdd)
            {
                if (++pointIndex > GlobleCache.areaModel.Points.Count) pointIndex = GlobleCache.areaModel.Points.Count;
            }
            else
            {
                if (--pointIndex < 0) pointIndex = 0;
            }
        }

        /// <summary>
        /// 重新整理目前在画图形的点数
        /// </summary>
        private void RestPointList()
        {
            //重新整理点的数组内容
            GlobleCache.areaModel.Points.RemoveRange(pointIndex, GlobleCache.areaModel.Points.Count - pointIndex);
        }

        

        /// <summary>
        /// 重置
        /// </summary>
        private void Reset(bool isRemoveFile = false)
        {
            InitBitmap();
            InitGraphics();
            if (isIndexPic)
            {
                graphics.DrawImage(indexImage, 0, 0);
            }
            mainPictureBox.Image = myBmp;
            if (!isRemoveFile) return;
            if (File.Exists(laneCsvPath)) File.Delete(laneCsvPath);
            if (File.Exists(lanePropertyCsvPath))
            {
                File.Delete(lanePropertyCsvPath);
                InitCsvFileAndLoad();
            }
        }

        /// <summary>
        /// 初始化bitmap
        /// </summary>
        private void InitBitmap()
        {
            if (CommomMethod.IsIndexedPixelFormat(indexImage.PixelFormat))
            {
                myBmp = new Bitmap(indexImage.Width, indexImage.Height, PixelFormat.Format32bppArgb);
                isIndexPic = true;
            }
            else
            {
                myBmp = new Bitmap(mainImageFilePath);
                isIndexPic = false;
            }
        }

        /// <summary>
        /// 初始化文件路径
        /// </summary>
        private void InitFilePath()
        {
            string path = mainImageFilePath.Replace(@"\", "/");
            path = path.Substring(0, path.LastIndexOf(@"/")) + "/";
            laneCsvPath = path + ConstantValue.LANECSV;
            lanePropertyCsvPath = path + ConstantValue.TRAFFIC_CONFIG;
            savePath = path + ConstantValue.SAVE_DIR + "/";
            areaJsonPath = path + ConstantValue.AREAS_JSON_PATH;
        }

        /// <summary>
        /// 初始化Graphics
        /// </summary>
        private void InitGraphics()
        {
            graphics = Graphics.FromImage(myBmp);
            graphics.SmoothingMode = SmoothingMode.HighQuality;  //图片柔顺模式选择
            graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;//高质量
            graphics.CompositingQuality = CompositingQuality.HighQuality;

        }

        /// <summary>
        /// 初始画CSV文件并加载到内存
        /// </summary>
        private void InitCsvFileAndLoad()
        {
            //加载完主图片后，在对应的目录下生成csv文件 并 初始化文件到内存中
            //加载csv初始数据到内存。
            if (isEdit)
            {
                
                GlobleCache.laneInfoCsv.Read(laneCsvPath);
                GlobleCache.lanePropertyCsv.Read(lanePropertyCsvPath);
            }
            else
            {
                FileMethod.WriteToFile(laneCsvPath,false);
                GlobleCache.laneInfoCsv.Read(laneCsvPath);
                //2.加载车道属性文件
                CSVHelper.InitCSVData(mainImageFilePath, OriginMainPicHight,OriginMainPicWith ).ContinueWith(task => { 
                    GlobleCache.lanePropertyCsv.Read(lanePropertyCsvPath);
                });
            }
        }

        /// <summary>
        /// 固化缓存中的配置文件到磁盘
        /// </summary>
        private void SaveCsvFile()
        {
            WaitWindowRotate.Show();
            //1.保存车道信息到CSV文件中
            GlobleCache.laneInfoCsv.Save(laneCsvPath);
            //2.保存车道属性信息到CSV中
            GlobleCache.lanePropertyCsv.Save(lanePropertyCsvPath);
            WaitWindowRotate.Hide();
        }

        /// <summary>
        /// 保存区域信息到JSON文件中
        /// </summary>
        private void SaveGlobleAreasJsonFile()
        {
            //将对象序列化保存到文件中
            var areaListJson = JsonConvert.SerializeObject(GlobleCache.areaList);
            using (FileStream fs = new FileStream(areaJsonPath, FileMode.Create))
            {

                //获得字节数组
                byte[] data = System.Text.Encoding.UTF8.GetBytes(areaListJson);
                //开始写入
                fs.Write(data, 0, data.Length);
            }

        }

        /// <summary>
        /// 反序列化文件
        /// </summary>
        private void DeSerializeFile()
        {
            string jsonDetail = System.IO.File.ReadAllText(areaJsonPath);
            GlobleCache.areaList = JsonConvert.DeserializeObject<List<AreaModel>>(jsonDetail);
        }

        /// <summary>
        /// 清理当前区域模型内容
        /// </summary>
        private void ClearAreaModel()
        {
            GlobleCache.areaModel.Points.Clear();
            GlobleCache.areaModel.IsSaved = false;
            GlobleCache.areaModel.IsLaneArea = false;
            GlobleCache.areaModel.LaneInfoModel = null;
            GlobleCache.areaModel.PropertyInfoModel = null;
        }

        #endregion

        
    }
}
